package com.daqian.chance.common.exception;

import com.daqian.chance.core.enums.ErrorCode;
import com.daqian.chance.core.exception.*;
import com.daqian.chance.core.rest.RestResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.Objects;

/**
 * 统一异常拦截
 */
@ControllerAdvice
@Slf4j
@Component
public class BaseExceptionHandler {

    private static final String ERROR_MSG = "系统错误，请重试";

    /**
     * 构建返回的msg
     *
     * @param e
     * @return
     */
    private String buildErrorMsg(Exception e) {
        log.error("", e);
        return e.getMessage() == null ? ERROR_MSG : e.getMessage();
    }

    /**
     * 全局异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public RestResult exception(Exception e) {
        return RestResult.fail(this.buildErrorMsg(e));
    }

    /**
     * 全局运行时异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = RuntimeException.class)
    @ResponseBody
    public RestResult runtimeException(RuntimeException e) {
        return RestResult.fail(this.buildErrorMsg(e));
    }

    /**
     * 请求参数数据类型不匹配
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = BindException.class)
    @ResponseBody
    public RestResult bindException(BindException e) {
        return RestResult.fail(this.buildErrorMsg(e));
    }

    /**
     * 未授权异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = UnauthorizedException.class)
    @ResponseBody
    public RestResult unauthorizedException(UnauthorizedException e) {
        return RestResult.fail(ErrorCode.UNAUTHORIZED.code(), this.buildErrorMsg(e));
    }

    /**
     * 未注册异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = UnregisteredException.class)
    @ResponseBody
    public RestResult unregisteredException(UnregisteredException e) {
        return RestResult.fail(ErrorCode.UNREGISTERED.code(), this.buildErrorMsg(e));
    }

    /**
     * 参数错误异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = IllegalArgumentException.class)
    @ResponseBody
    public RestResult illegalArgumentException(IllegalArgumentException e) {
        return RestResult.fail(this.buildErrorMsg(e));
    }

    /**
     * 全局运行时异常 ChanceException
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = ChanceException.class)
    @ResponseBody
    public RestResult chanceException(ChanceException e) {
        return RestResult.fail(this.buildErrorMsg(e));
    }

    /**
     * 全局ES异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = ElasticSearchException.class)
    @ResponseBody
    public RestResult ElasticSearchException(ElasticSearchException e) {
        return RestResult.fail(this.buildErrorMsg(e));
    }


    /**
     * 自定义service异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = ServiceException.class)
    @ResponseBody
    public RestResult serviceException(ServiceException e) {
        return RestResult.fail(this.buildErrorMsg(e));
    }

    @ResponseBody
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public RestResult exceptionHandler(MethodArgumentNotValidException e) {
        return RestResult.fail(ErrorCode.BAD_REQUEST.code(),Objects.requireNonNull(e.getBindingResult().getFieldError()).getDefaultMessage());
    }
}